package dai.samples.batch.rw;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import dai.samples.batch.entity.BatchEntity;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.batch.item.database.builder.JdbcBatchItemWriterBuilder;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.batch.item.file.builder.FlatFileItemWriterBuilder;
import org.springframework.batch.item.file.transform.LineAggregator;
import org.springframework.batch.item.json.JacksonJsonObjectMarshaller;
import org.springframework.batch.item.json.builder.JsonFileItemWriterBuilder;
import org.springframework.batch.item.xml.StaxEventItemWriter;
import org.springframework.batch.item.xml.builder.StaxEventItemWriterBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.oxm.xstream.XStreamMarshaller;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * 写数据的配置
 * @author daify
 */
@Configuration
public class WriteConfig {

    @Autowired
    DataSource dataSource;

    /**
     * JSON写数据
     * @return
     */
    @Bean(name = "itemJsonWriter")
    public ItemWriter<BatchEntity> itemJsonWriter() {
        String patch = "target/test-outputs/writer/itemJsonWriter.json";
        return new JsonFileItemWriterBuilder<BatchEntity>()
                .jsonObjectMarshaller(new JacksonJsonObjectMarshaller<>())
                .resource(new FileSystemResource(patch))
                .name("itemJsonWriter")
                .build();
    }

    /**
     * 数据写到文件中
     * @return
     */
    @Bean(name = "itemLineWriter")
    public FlatFileItemWriter<BatchEntity> itemLineWriter(){
        String patch = "target/test-outputs/writer/itemLineWriter.txt";
        return new FlatFileItemWriterBuilder<BatchEntity>()
                .lineAggregator(new BatchEntityDoLineAggregator())
                .resource(new FileSystemResource(patch))
                .name("itemLineWriter")
                .build();
    }

    /**
     * 写入文件中行形式
     */
    class BatchEntityDoLineAggregator implements LineAggregator<BatchEntity> {
        ObjectMapper mapper = new ObjectMapper();

        @Override
        public String aggregate(BatchEntity batchEntity) {
            try {
                return mapper.writeValueAsString(batchEntity);
            } catch (JsonProcessingException e) {
                throw new RuntimeException("unable to writer...",e);
            }
        }

    }

    /**
     * XML写数据
     * @return
     */
    @Bean(name = "itemXmlWriter")
    public StaxEventItemWriter<BatchEntity> itemXmlWriter() {
        XStreamMarshaller marshaller = new XStreamMarshaller();
        Map<String, Class> aliases = new HashMap<>();
        aliases.put("batchEntity", BatchEntity.class);
        marshaller.setAliases(aliases);

        String patch = "target/test-outputs/writer/itemXmlWriter.xml";
        return new StaxEventItemWriterBuilder<BatchEntity>()
                .rootTagName("batchEntity")
                .resource(new FileSystemResource(patch))
                .name("itemXmlWriter")
                .marshaller(marshaller)
                .build();
    }


    /**
     * 数据写到数据库中
     * @return
     */
    @Bean(name = "itemJDBCWriter")
    public JdbcBatchItemWriter<BatchEntity> itemJDBCWriter() {
        return new JdbcBatchItemWriterBuilder<BatchEntity>()
                .dataSource(dataSource)
                .sql("insert into batch_entity " +
                        "(entity_id,first_name,last_name,age,full_name,is_adult,hello_message)" +
                        "values (:entityId,:firstName,:lastName,:age,:fullName,false,:helloMessage)")
                .itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<BatchEntity>())
                .build();
    }

}
